import { Root } from "../../../../../Core/Module/Entity/Root";
import { EventSystem } from "../../../../../Core/Module/EventSystem/EventSystem";
import { Awake1System } from "../../../../../Core/Module/EventSystem/IAwakeSystem";
import { ServiceType } from "../../../../../Core/Module/Network/AService";
import { NetServices } from "../../../../../Core/Module/Network/NetServices";
import { WService } from "../../../../../Core/Module/Network/WService";
import { TimeHelper } from "../../../../../Core/Module/Time/TimeHelper";
import { ExpandOf, FriendOf, ObjectSystemAttribute } from "../../../../../Decorator/Decorator";
import { NetServerComponent, NetServerComponentOnRead } from "../../../../Model/Server/Module/Message/NetServerComponent";
import { OpcodeHelper } from "../../../../Model/Share/Module/Message/OpcodeHelper";
import { Session } from "../../../../Model/Share/Module/Message/Session";
import { SessionAcceptTimeoutComponent } from "../../../../Model/Share/Module/Message/SessionAcceptTimeoutComponent";
import { SessionIdleCheckerComponent } from "../../../../Model/Share/Module/Message/SessionIdleCheckerComponent";


/**
 * 使用 Expand 扩展方法
 * 
 * 必须作出以下申明，才能调用对象的扩展方法
 */
declare module "../../../../Model/Server/Module/Message/NetServerComponent" {

    interface NetServerComponent {

        OnAccept(channelId: number, ipEndPoint: string): void;
        OnRead(channelId: number, actorId: number, message: Object): void;
        OnError(channelId: number, error: number): void;

    }

}

@ExpandOf(NetServerComponent)
export class NetServerComponentSystem {

    private static OnAccept(self: NetServerComponent, channelId: number, ipEndPoint: string): void {
        // console.log(`NetServerComponentSystem OnAccept`);
        // console.log(self.ServiceId);
        // console.log(channelId);
        // console.log(ipEndPoint);

        let session = self.AddChildWithId<Session, number>(Session, channelId, self.ServiceId);
        session.RemoteAddress = ipEndPoint;

        session.AddComponent<SessionAcceptTimeoutComponent>(SessionAcceptTimeoutComponent);
        session.AddComponent<SessionIdleCheckerComponent>(SessionIdleCheckerComponent);
    }

    private static OnRead(self: NetServerComponent, channelId: number, actorId: number, message: Object): void {
        let session = self.GetChild<Session>(channelId);
        if (session == null) {
            return;
        }
        session.LastRecvTime = TimeHelper.ClientNow();

        OpcodeHelper.LogMsg(self.DomainZone(), message);

        let netServerComponentOnRead = new NetServerComponentOnRead();
        {
            netServerComponentOnRead.Session = session;
            netServerComponentOnRead.Message = message;
        }
        // 派发事件
        EventSystem.Instance.Publish(Root.Instance.Scene, netServerComponentOnRead);
    }

    private static OnError(self: NetServerComponent, channelId: number, error: number): void {
        let session = self.GetChild<Session>(channelId);
        if (session == null) {
            return;
        }

        session.Error = error;
        session.Dispose();
    }

}

@FriendOf(NetServerComponent)
@ObjectSystemAttribute()
export class NetServerComponentAwake1System extends Awake1System<NetServerComponent, string> {

    Awake(self: NetServerComponent, ipEndPoint: string): void {
        self.ServiceId = NetServices.Instance.AddService(new WService(ipEndPoint, ServiceType.Outer));
        NetServices.Instance.RegisterAcceptCallback(self.ServiceId, self.OnAccept.bind(self));
        NetServices.Instance.RegisterReadCallback(self.ServiceId, self.OnRead.bind(self));
        NetServices.Instance.RegisterErrorCallback(self.ServiceId, self.OnError.bind(self));

        // console.log(`NetServerComponentAwakeSystem self.ServicedId = ${self.ServiceId}`);
    }

}